/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.agi.ia.kohonen.unidimensao;

/**
 *
 * @author Renato
 */
public class Camada {
    private Neuron[][] rede;
    private int quantidadeNeurons;
    public Camada(int tamanhoEntrada, int quantidadeNeurons){
        rede=new Neuron[quantidadeNeurons][quantidadeNeurons];
        for(int i=0;i<quantidadeNeurons;i++){
            for(int j=0;j<quantidadeNeurons;j++){
                rede[i][j]=new Neuron(tamanhoEntrada);
            }
        }
        this.quantidadeNeurons=quantidadeNeurons;
        this.configurarRede(new InicializadorPesosPadrao());        
    }
    
    public void setEntrada(double[] entrada){
        for(int i=0;i<quantidadeNeurons;i++){
            for(int j=0;j<quantidadeNeurons;j++){
            rede[i][j].setEntrada(entrada);
            }
        }
    }
    
    public void setInicializadorPesos(InicializadorPesos inicializador){
        this.configurarRede(inicializador);        
    }   
    
    private void configurarRede(InicializadorPesos inicializador){
        for(int i=0;i<quantidadeNeurons;i++){  
            for(int j=0;j<quantidadeNeurons;j++){
                rede[i][j].setInicializadorPesos(inicializador);
            }
        }       
    }
        
    public void inicializarPesos(){
        for(int i=0;i<quantidadeNeurons;i++){            
            for(int j=0;j<quantidadeNeurons;j++){
                rede[i][j].inicializarPesos();
            }
        }
    }
    
    public void calcularEntrada(){
        for(int i=0;i<quantidadeNeurons;i++){
            for(int j=0;j<quantidadeNeurons;j++){
                rede[i][j].calcularEntrada();
            }
        }
    }
    
    int vencedorX;
    int vencedorY;
    
    public void calcularVencedor(){
        double euclidiana;
        euclidiana=rede[0][0].euclidiana;
        for(int i=0;i<quantidadeNeurons;i++){
            for(int j=0;j<quantidadeNeurons;j++){
                if(rede[i][j].euclidiana<euclidiana){
                    vencedorX=i;
                    vencedorY=j;
                    euclidiana=rede[i][j].euclidiana;
                }
            }
        }
    }
    
    public void atualizarCamada(double fator){
        double d;
        for(int i=0;i<quantidadeNeurons;i++){
            double dx;
            dx=vencedorX-i;
            dx=dx*dx;
            for(int j=0;j<quantidadeNeurons;j++){
                double dy;
                double f;   
                dy=vencedorY-j;
                dy=dy*dy;
                d=dx+dy;
                f=1 / (d/fator) +1;
                rede[i][j].atualizar(f);
            }
        }
    }
    
    public void setFatorAtualizacao(double fator){
          for(int i=0;i<quantidadeNeurons;i++){
               for(int j=0;j<quantidadeNeurons;j++){
                    rede[i][j].setFatorAtualizacao(fator) ;
               }
          }
    }
    
    
    public double[] getPesoVencedor(){
        Neuron winner;
        winner=rede[vencedorX][vencedorY];
        return winner.peso;
    }
}
